package entities;

import util.BigPrime;
import util.CountPred;
import eduni.simjava.Sim_entity;
import eduni.simjava.Sim_event;
import eduni.simjava.Sim_negexp_obj;
import eduni.simjava.Sim_port;
import eduni.simjava.Sim_system;

public class Lan extends Sim_entity implements Measurable {

	private Sim_port in;

	private Sim_negexp_obj delay;

	private int n;

	private double totalResponseTime;

	private double utilizationTime;

	private double total;
	
	private float mean_queue_sz = .0f;
	private int queue_samples_num = 0;
	
	public Lan(String name, double mi) {
		super(name);

		in = new Sim_port("in");

		add_port(in);

		delay = new Sim_negexp_obj("Time to send one bit", 1 / mi, BigPrime
				.getSeed());
	}

	@Override
	public void body() {
		Sim_event event = new Sim_event();

		n = 0;
		totalResponseTime = 0.0;		
		utilizationTime = 0.0;
		
		total = Sim_system.sim_clock();	

		while (true) {
			
			CountPred cpred = new CountPred();
			sim_select(cpred, event);
			{
				mean_queue_sz = (mean_queue_sz*queue_samples_num + cpred.get_count())/
				(++queue_samples_num);
			}
			
			sim_get_next(event);
			// System.out.println("Router: Recebido pacote no momento " +
			// Sim_system.sim_clock());

			if (event.get_tag() == -1)
				break;

			n++;
			// processando

			double processingTime = delay.sample() * event.get_tag();
			utilizationTime += processingTime;
			sim_hold(processingTime);

			totalResponseTime += Sim_system.sim_clock() - event.event_time();
		}

		total = Sim_system.sim_clock() - total;

		/*System.out.println(lanName
				+ ": mean N = "
				+ Double.valueOf(meanN()).toString().replace(
						'.', ','));
		System.out.println(lanName
				+ ": mean response time = "
				+ Double.valueOf(getR()).toString().replace('.',
						','));
		System.out.println(lanName
				+ ": mean service time = "
				+ Double.valueOf(getS()).toString().replace('.',
						','));
		System.out.println(lanName
				+ ": utilization = "
				+ Double.valueOf(getU()).toString().replace(
						'.', ','));*/

	}

	public double getU() {
		return utilizationTime / total;
	}

	public double getS() {
		return utilizationTime / n;
	}

	public double getR() {
		return totalResponseTime / n;
	}

	public double meanN() {
		return totalResponseTime / total;
	}

	@Override
	public double meanQ() {
		// TODO Auto-generated method stub
		return mean_queue_sz;
	}
	
}
